package com.tdam2013.grupo07.sync;

import java.util.ArrayList;
import java.util.HashMap;

import com.tdam2013.grupo07.data.DatabaseHelper;
import com.tdam2013.grupo07.data.DatabaseHelperSingleton;

import android.accounts.Account;
import android.accounts.OperationCanceledException;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;

public class ContactsSyncAdapterService extends Service {
	private static final String TAG = "ContactsSyncAdapterService";
	private static SyncAdapterImpl sSyncAdapter = null;
	private static ContentResolver mContentResolver = null;

	public ContactsSyncAdapterService() {
		super();
	}

	private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
		private Context mContext;

		public SyncAdapterImpl(Context context) {
			super(context, true);
			mContext = context;
		}

		@Override
		public void onPerformSync(Account account, Bundle extras,
				String authority, ContentProviderClient provider,
				SyncResult syncResult) {
			try {
				ContactsSyncAdapterService.performSync(mContext, account,
						extras, authority, provider, syncResult);
			} catch (OperationCanceledException e) {
			}
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		IBinder ret = null;
		ret = getSyncAdapter().getSyncAdapterBinder();
		return ret;
	}

	private SyncAdapterImpl getSyncAdapter() {
		if (sSyncAdapter == null)
			sSyncAdapter = new SyncAdapterImpl(this);
		return sSyncAdapter;
	}

	private static void performSync(Context context, Account account,
			Bundle extras, String authority, ContentProviderClient provider,
			SyncResult syncResult) throws OperationCanceledException {

		HashMap<String, Long> localContacts = new HashMap<String, Long>();
		mContentResolver = context.getContentResolver();
		Log.i(TAG, "performSync: " + account.toString());

		// Load the local Last.fm contacts
		Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon()
				.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
				.appendQueryParameter(RawContacts.ACCOUNT_TYPE, account.type)
				.build();
		Cursor c1 = mContentResolver.query(rawContactUri, new String[] {
				BaseColumns._ID, RawContacts.SYNC1 }, null, null, null);
		while (c1.moveToNext()) {
			localContacts.put(c1.getString(1), c1.getLong(0));
		}

		// ArrayList<ContentProviderOperation> operationList = new
		// ArrayList<ContentProviderOperation>();

		DatabaseHelper dbHelper = DatabaseHelperSingleton.getInstance(context)
				.getDatabaseHelper();
		Cursor cursor = dbHelper.seleccionarContactos();

		// String selection = "";
		// LinkedList<String> selectionArgs = new LinkedList<String>();
		//
		// Uri contentUri = searchText.length() == 0 ?
		// ContactsContract.Contacts.CONTENT_URI
		// : Uri.withAppendedPath(
		// ContactsContract.Contacts.CONTENT_FILTER_URI,
		// Uri.encode(searchText));
		// SharedPreferences preferences = PreferenceManager
		// .getDefaultSharedPreferences(this);
		// String contactsOrder = preferences.getString(
		// getResources().getString(
		// R.string.lista_ordenamiento_contactos_alfabetico),
		// getResources().getString(
		// R.string.ajustes_ordenamiento_opciones_asc));
		// if (preferences
		// .getBoolean(
		// getResources()
		// .getString(
		// R.string.activity_ajustes_filtrar_contactos_opcion_telefono_key),
		// false)) {
		// selection += Contacts.HAS_PHONE_NUMBER + " = ?";
		// selectionArgs.add("1");
		// }
		// get (this, contentUri, contactsQueryProjection,
		// selection, selectionArgs.toArray(new String[selectionArgs
		// .size()]), String.format("%s %s",
		// ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
		// contactsOrder));
		Cursor contactCursor = null;
		try {

			while (cursor.moveToNext()) {
				if (!localContacts.containsKey(cursor.getString(1))) {
					contactCursor = mContentResolver.query(
							ContactsContract.Contacts.CONTENT_URI,
							new String[] { ContactsContract.Contacts._ID,
									ContactsContract.Contacts.DISPLAY_NAME },
							ContactsContract.Contacts._ID + " = ?",
							new String[] { cursor.getString(0) }, null);
					contactCursor.moveToFirst();
					addContact(account, contactCursor.getString(1),
							cursor.getString(1));
					Log.e(TAG, "CREADO: " + account.toString());
				}
			}
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} finally {
			if (cursor != null && !cursor.isClosed()) {
				cursor.close();
			}
			if (contactCursor != null && !contactCursor.isClosed()) {
				contactCursor.close();
			}
		}
	}

	private static void addContact(Account account, String displayname,
			String username) {
		Log.i(TAG, "Adding contact: " + displayname);
		ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();

		// Create our RawContact
		ContentProviderOperation.Builder builder = ContentProviderOperation
				.newInsert(RawContacts.CONTENT_URI);
		builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
		builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
		builder.withValue(RawContacts.SYNC1, username);
		operationList.add(builder.build());

		// Create a Data record of common type 'StructuredName' for our
		// RawContact
		builder = ContentProviderOperation
				.newInsert(ContactsContract.Data.CONTENT_URI);
		builder.withValueBackReference(
				ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID,
				0);
		builder.withValue(
				ContactsContract.Data.MIMETYPE,
				ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
		builder.withValue(
				ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
				displayname);
		operationList.add(builder.build());

		// Create a Data record of custom type
		// "vnd.android.cursor.item/vnd.7app.android.profile" to display a
		// link to the Last.fm profile
		builder = ContentProviderOperation
				.newInsert(ContactsContract.Data.CONTENT_URI);
		builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
		builder.withValue(ContactsContract.Data.MIMETYPE,
				"vnd.android.cursor.item/vnd.7app.android.profile");
		builder.withValue(ContactsContract.Data.DATA1, username);
		builder.withValue(ContactsContract.Data.DATA2, "7app Chat");
		builder.withValue(ContactsContract.Data.DATA3, username);
		operationList.add(builder.build());

		try {
			mContentResolver.applyBatch(ContactsContract.AUTHORITY,
					operationList);
		} catch (Exception e) {
			Log.e(TAG, "Something went wrong during creation! " + e);
			e.printStackTrace();
		}
	}
}